package exceltojson

import (
	"encoding/json"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/xuri/excelize/v2"
)

func Exceltojson(excelPath string, configName string) error {
	f, err := excelize.OpenFile(excelPath)
	if err != nil {
		return err
	}
	defer f.Close()

	sheets := f.GetSheetList()
	mapSheetData := make(map[string]interface{})
	for _, v := range sheets {
		if v == "common" {
			readCommonSheet(f, v, mapSheetData)
		} else {
			readArraySheet(f, v, mapSheetData)
		}
	}

	jsonData, err := json.Marshal(mapSheetData)
	if err != nil {
		return err
	}

	sheetName := configName + ".json"

	saveJson(sheetName, string(jsonData))

	return nil
}

func readCommonSheet(f *excelize.File, sheetName string, mapData map[string]interface{}) {
	rows, err := f.GetRows(sheetName)
	if err != nil {
		return
	}

	rows = rows[1:]
	for _, row := range rows {
		key := strings.TrimSpace(row[1])
		value := strings.TrimSpace(row[2])
		dataType := strings.TrimSpace(row[3])

		if dataType == "number" {
			if num, err := strconv.Atoi(value); err == nil {
				mapData[key] = num
			}
		} else {
			mapData[key] = value
		}
	}
}

func readArraySheet(f *excelize.File, sheetName string, mapData map[string]interface{}) {
	rows, err := f.GetRows(sheetName)
	if err != nil {
		return
	}

	rows = rows[1:]
	headers := make([]string, len(rows[0]))
	for j, col := range rows[0] {
		headers[j] = strings.TrimSpace(col)
	}

	rows = rows[1:]
	dataTypes := make([]string, len(rows[0]))
	for j, col := range rows[0] {
		dataTypes[j] = strings.TrimSpace(col)
	}

	rows = rows[1:]
	rowsLen := len(rows)
	rowDatas := make([]interface{}, rowsLen)

	for i, row := range rows {
		mapRowData := make(map[string]interface{})

		for j, col := range row {
			header := headers[j]
			cellValue := strings.TrimSpace(col)

			mapRowData[header] = cellValue
			if dataTypes[j] == "number" {
				if num, err := strconv.Atoi(cellValue); err == nil {
					mapRowData[header] = num
				}
			}
		}
		rowDatas[i] = mapRowData
	}
	mapData[sheetName] = rowDatas
}

func saveJson(fileName string, content string) {

	_, err := os.Stat("./json/")
	if err != nil {
		if os.IsNotExist(err) {
			os.MkdirAll("./json/", os.ModePerm)
		}
	}

	file, err := os.Create("./json/" + fileName)
	if err != nil {
		fmt.Println("Error creating file:", err)
		return
	}

	_, err = file.WriteString(content)
	if err != nil {
		fmt.Println("Error writing to file:", err)
		return
	}

	defer file.Close()
}
